package com.wardrobe.soa.api.goods_order;

import com.thoughtworks.xstream.XStream;
import com.wardrobe.dao.address.AddressDao;
import com.wardrobe.dao.booking.BookingDao;
import com.wardrobe.dao.booking_order.BookingOrderDao;
import com.wardrobe.dao.goods.GoodsDao;
import com.wardrobe.dao.goods_order.GoodsOrderDao;
import com.wardrobe.dao.order_prepay_dao.OrderPrePayDao;
import com.wardrobe.dao.shop.ShopDao;
import com.wardrobe.domain.address.AddressBean;
import com.wardrobe.domain.booking.BookingShowBean;
import com.wardrobe.domain.booking_order.BookingOrderShowBean;
import com.wardrobe.domain.booking_order.BookingOrderbean;
import com.wardrobe.domain.common.BookingOrderPayFromBean;
import com.wardrobe.domain.common.GoodsOrderPayFromBean;
import com.wardrobe.domain.common.WeixinPayResult;
import com.wardrobe.domain.goods.GoodsShowBean;
import com.wardrobe.domain.goods_order.GoodsOrderBean;
import com.wardrobe.domain.goods_order.GoodsOrderShowBean;
import com.wardrobe.domain.orderprepay.OrderPrepayBean;
import com.wardrobe.domain.orderprepay.OrderPrepayShowBean;
import com.wardrobe.domain.shop.ShopShowBean;
import com.wardrobe.mapper.slave.goods_model.GoodsModelSlaveMapper;
import com.wardrobe.soa.api.booking_order.BookingOrderDetail;
import com.wardrobe.soa.api.booking_order.BookingOrderResponse;
import com.wardrobe.soa.common.WeChatConsant;
import com.wardrobe.soa.utils.CommonUtil;
import com.wardrobe.soa.utils.HttpClientUtils;
import com.wardrobe.soa.utils.NumberUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;

/**
 * Created by Administrator on 2018/11/20.
 */
@Service
public class GoodsOrderService {
    private static final Logger logger = LoggerFactory.getLogger(GoodsOrderService.class);
    @Autowired
    private GoodsOrderDao goodsOrderDao;
    @Autowired
    private ShopDao shopDao;
    @Autowired
    private GoodsDao goodsDao;
    @Autowired
    private AddressDao addressDao;
    @Autowired
    private OrderPrePayDao orderPrePayDao;
    @Autowired
    private GoodsModelSlaveMapper goodsModelSlaveMapper;
    @Transactional
    public synchronized long saveGoodsOrder(GoodsOrderBean orderbean){
        orderbean.setOrderId(System.currentTimeMillis()+new Random().nextInt(10));
        int flag = goodsOrderDao.insertGoodsOrder(orderbean);
        if (flag==1){
            return orderbean.getOrderId();
        }else {
            return 0;
        }
    }
    public int modifyOrderStatus(long orderId, int status){
        return goodsOrderDao.updateGoodsOrderByOrderId(orderId,status);
    }
    public List<GoodsOrderResponse> goodsOrderList(long userId, int status){
        List<GoodsOrderShowBean> goodsOrderList = goodsOrderDao.selectGoodsOrder(userId,status);
        List<GoodsOrderResponse> list = new ArrayList<>();
        goodsOrderList.stream().forEach(goodsOrder->{
            ShopShowBean shop = shopDao.selectShopById(goodsOrder.getShopId());
            GoodsShowBean goodsShowBean = goodsDao.selectGoodsById(goodsOrder.getGoodsId());
            goodsOrder.setCreateTime(goodsOrder.getCreateTime().substring(0,goodsOrder.getCreateTime().length()-2));
            BigDecimal price = goodsModelSlaveMapper.getGoodsByType(goodsOrder.getSpecifications(), goodsOrder.getGoodsId());
            GoodsOrderResponse response =  GoodsOrderResponse.builder()
                    .id(goodsOrder.getId())
                    .shopId(goodsOrder.getShopId())
                    .orderId(goodsOrder.getOrderId())
                    .shopName(shop.getShopName())
                    .showPicture(goodsShowBean.getShowPicture().split(";").length>0?goodsShowBean.getShowPicture().split(";")[0]:"")
                    .name(goodsShowBean.getGoodName())
                    .price(price)
                    .status(goodsOrder.getStatus())
                    .createTime(goodsOrder.getCreateTime())
                    .telphone(shop.getTelphone())
                    .buyNum(goodsOrder.getBuyNum())
                    .specifications(goodsOrder.getSpecifications())
                    .build();
            list.add(response);
        });
        return list;
    }

    public GoodsOrderDetail getGoodsOrderDetails(long orderId){
        GoodsOrderShowBean goodsOrder = goodsOrderDao.selectGoodsOrderByOrderId(orderId);
        ShopShowBean shop = shopDao.selectShopById(goodsOrder.getShopId());
//        AddressBean addressBean = addressDao.selectDefaultAddress(goodsOrder.getUserId());
        AddressBean addressBean =addressDao.selectAddressById(goodsOrder.getAddressId());
        GoodsShowBean goodsShowBean = goodsDao.selectGoodsById(goodsOrder.getGoodsId());
        goodsOrder.setCreateTime(goodsOrder.getCreateTime().substring(0,goodsOrder.getCreateTime().length()-2));
        BigDecimal price = goodsModelSlaveMapper.getGoodsByType(goodsOrder.getSpecifications(), goodsOrder.getGoodsId());
        return GoodsOrderDetail.builder()
                .id(goodsOrder.getId())
                .orderId(orderId)
                .goodsId(goodsShowBean.getId())
                .addressBean(addressBean)
                .shopId(goodsOrder.getShopId())
                .shopName(shop.getShopName())
                .name(goodsShowBean.getGoodName())
                .showPicture(goodsShowBean.getShowPicture().split(";").length>0?goodsShowBean.getShowPicture().split(";")[0]:"")
                .remark(goodsOrder.getRemark())
                .createTime(goodsOrder.getCreateTime())
                .price(price)
                .payTime(goodsOrder.getPayTime())
                .buyNum(goodsOrder.getBuyNum())
                .specifications(goodsOrder.getSpecifications())
                .build();
    }
    @Transactional
    public Map<String,Object> weixinPay(GoodsOrderPayFromBean fromBean) throws Exception {
        long orderId = NumberUtil.parseLong(fromBean.getOutTradeNo(), 0);
        OrderPrepayShowBean showBean = orderPrePayDao.getOrderPrepayByOrderId(orderId);
        if(showBean!=null){
            long createTime = showBean.getCreateTime();
            long nowTime = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"));
            double hours= CommonUtil.getBetweenHours(createTime,nowTime);
            if(hours>2){
                orderPrePayDao.deleteOrderPrepay(orderId);
                goodsOrderDao.updateGoodsOrderByOrderId(orderId,-1);
            }else{
                //直接给prepayid
                TreeMap<String,Object> payMap = new TreeMap();
                payMap.put("appid", WeChatConsant.appId);
                payMap.put("partnerid",WeChatConsant.wechatPayMchId);
                payMap.put("prepayid",showBean.getPrepayId());
                payMap.put("package","Sign=WXPay");
                payMap.put("noncestr",String.valueOf(System.currentTimeMillis()));
                payMap.put("timestamp",LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8")));
                logger.warn("payMap={}",payMap);
                payMap.put("sign",CommonUtil.getSignValue(payMap));
                return payMap;
            }
        }else{
            TreeMap<String, Object> params = new TreeMap<>();
            params.put("appid", WeChatConsant.appId);
            params.put("mch_id",WeChatConsant.wechatPayMchId);
            params.put("nonce_str",String.valueOf(System.currentTimeMillis()));
            params.put("body",fromBean.getBody());
            params.put("out_trade_no",fromBean.getOutTradeNo());
            params.put("total_fee",fromBean.getTotalFee());
            params.put("spbill_create_ip",fromBean.getSpbillCreateIp());
            params.put("notify_url", CommonUtil.getRealmNameUrl()+fromBean.getNotifyUrl());
            params.put("trade_type",fromBean.getTradeType());
            String sign = CommonUtil.getSignValue(params);
            logger.warn("sign={}",sign);
            String xmlData = CommonUtil.formatUnifiedorderParam(params, sign);
            logger.warn("xmlData={}",xmlData);
            String post = HttpClientUtils.sendPost(WeChatConsant.weixin_pay_unifiedorder_url, xmlData);
            Map<String, Object> res = CommonUtil.getXmlValue(post);
            logger.warn("res={}",res);
            if(res.get("return_code").equals(WeChatConsant.SUCCESS)){
                TreeMap<String,Object> payMap = new TreeMap();
                payMap.put("appid", WeChatConsant.appId);
                payMap.put("partnerid",res.get("mch_id"));
                payMap.put("prepayid",res.get("prepay_id"));
                payMap.put("package","Sign=WXPay");
                payMap.put("noncestr",res.get("nonce_str"));
                payMap.put("timestamp",LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8")));
                logger.warn("payMap={}",payMap);
                payMap.put("sign",CommonUtil.getSignValue(payMap));
                OrderPrepayBean bean = new OrderPrepayBean();
                bean.setOrderId(orderId);
                bean.setCreateTime(LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8")));
                bean.setPrepayId((String) res.get("prepay_id"));
                int flag = orderPrePayDao.insertOrderPrepay(bean);
                if(flag==1){
                    return payMap;
                }else{
                    return null;
                }
            }
            return res;
        }
        return null;
    }
    @Transactional
    public void weixinCallBack(HttpServletRequest request, HttpServletResponse response) throws Exception {
        StringBuffer sb = new StringBuffer();
        String reqParamss = CommonUtil.read(request.getInputStream());
        logger.info("-------支付结果:{}",reqParamss);
        if(reqParamss==null||"".equals(reqParamss)){
            logger.warn("weixinCallBack Request data error");
        }else{
            XStream xStream = new XStream();
            xStream.alias("xml", WeixinPayResult.class);
            WeixinPayResult returnInfo = (WeixinPayResult)xStream.fromXML(reqParamss);
            String return_code=returnInfo.getReturn_code();
            if(return_code.equals(WeChatConsant.SUCCESS)){//支付成功
                if(returnInfo.getResult_code().equals(WeChatConsant.SUCCESS)){
                    long orderId = NumberUtil.parseLong(returnInfo.getOut_trade_no(), 0);
                    if(orderId == 0){
                        logger.warn("orderId 格式错误！");
                        throw new Exception();
                    }
                    GoodsOrderShowBean goodsOrder = goodsOrderDao.selectGoodsOrderByOrderId(orderId);
                    if(goodsOrder.getStatus()==1){
                        sb.append("<xml><return_code>SUCCESS</return_code><return_msg>OK</return_msg></xml>");
                    }else{
                        int flag = goodsOrderDao.updateGoodsOrderByOrderId(orderId,1);
                        if(flag != 1){
                            logger.warn("订单状态修改失败！");
                        }else{
                            sb.append("<xml><return_code>SUCCESS</return_code><return_msg>OK</return_msg></xml>");
                        }
                    }
                }else{
                    sb.append("<xml><return_code>FAIL</return_code><return_msg>"+returnInfo.getReturn_msg()+"</return_msg></xml>");
                }
            }else{
                sb.append("<xml><return_code>FAIL</return_code><return_msg>"+returnInfo.getReturn_msg()+"</return_msg></xml>");
            }
            logger.warn("weixinCallBack-->{}",returnInfo.toString());
        }
        response.reset();
        response.getWriter().append(sb.toString());
    }
}
